package com.example.gulimall.product.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.example.common.constant.ProductConstant;
import com.example.gulimall.product.dao.AttrAttrgroupRelationDao;
import com.example.gulimall.product.entity.AttrAttrgroupRelationEntity;
import com.example.gulimall.product.entity.AttrGroupEntity;
import com.example.gulimall.product.entity.CategoryEntity;
import com.example.gulimall.product.service.AttrGroupService;
import com.example.gulimall.product.service.CategoryService;
import com.example.gulimall.product.vo.AttrGroupRelationVo;
import com.example.gulimall.product.vo.AttrPageResponseVo;
import com.example.gulimall.product.vo.AttrVo;
import com.example.gulimall.product.vo.item.SpuBaseAttrVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.common.utils.PageUtils;
import com.example.common.utils.Query;

import com.example.gulimall.product.dao.AttrDao;
import com.example.gulimall.product.entity.AttrEntity;
import com.example.gulimall.product.service.AttrService;
import org.springframework.transaction.annotation.Transactional;


@Service("attrService")
public class AttrServiceImpl extends ServiceImpl<AttrDao, AttrEntity> implements AttrService {

    @Autowired
    private AttrAttrgroupRelationDao attrAttrgroupRelationDao;
    @Autowired
    private CategoryService categoryService;
    @Autowired
    private AttrGroupService attrGroupService;


    @Override
    public PageUtils queryPage(Map<String, Object> params, String attrType, Long catelogId) {
        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                Wrappers.<AttrEntity>lambdaQuery()
                        .eq(catelogId != 0, AttrEntity::getCatelogId, catelogId)
                        .eq(AttrEntity::getAttrType, "base".equalsIgnoreCase(attrType)
                                ? ProductConstant.AttrEnum.TYPE_ATTR_BASE.getCode()
                                : ProductConstant.AttrEnum.TYPE_ATTR_SALE.getCode())
        );
        PageUtils pageUtils = new PageUtils(page);
        try {

            List<AttrPageResponseVo> list = page.getRecords().stream().map(
                    a -> {
                        AttrPageResponseVo vo = new AttrPageResponseVo();
                        BeanUtils.copyProperties(a, vo);

                        AttrAttrgroupRelationEntity entity = this.attrAttrgroupRelationDao.selectOne(
                                Wrappers.<AttrAttrgroupRelationEntity>lambdaQuery()
                                        .eq(AttrAttrgroupRelationEntity::getAttrId, a.getAttrId())
                        );

                        if (Objects.nonNull(entity)) {
                            vo.setCatelogName(entity.getCatelogName());
                            vo.setGroupName(entity.getGroupName());
                        }

                        return vo;
                    }
            ).collect(Collectors.toList());

            pageUtils.setList(list);
            return pageUtils;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveAttr(AttrVo attr) {
        this.save(attr);

        // 销售属性，不需要保存关联关系
        if (attr.getAttrType() == ProductConstant.AttrEnum.TYPE_ATTR_SALE.getCode()) {
            return;
        }

        CategoryEntity categoryEntity = this.categoryService.getById(attr.getCatelogId());
        AttrAttrgroupRelationEntity entity = new AttrAttrgroupRelationEntity();

        if (Objects.nonNull(attr.getAttrGroupId())) {
            entity.setAttrGroupId(attr.getAttrGroupId());
            entity.setGroupName(this.attrGroupService.getById(attr.getAttrGroupId()).getAttrGroupName());
            entity.setAttrId(attr.getAttrId());
            entity.setAttrName(attr.getAttrName());
            entity.setCatelogName(categoryEntity.getName());
            this.attrAttrgroupRelationDao.insert(entity);
        }
    }

    @Override
    public AttrPageResponseVo getAttrInfo(Long attrId) {
        AttrPageResponseVo vo = new AttrPageResponseVo();

        AttrEntity attrEntity = this.baseMapper.selectById(attrId);
        BeanUtils.copyProperties(attrEntity, vo);

        AttrAttrgroupRelationEntity entity = this.attrAttrgroupRelationDao.selectOne(
                Wrappers.<AttrAttrgroupRelationEntity>lambdaQuery()
                        .eq(AttrAttrgroupRelationEntity::getAttrId, attrId)
        );
        vo.setGroupName(entity.getGroupName());

        vo.setCatelogName(entity.getCatelogName());
        vo.setAttrGroupId(entity.getAttrGroupId());
        vo.setCatelogPath(this.categoryService.selectCatalogPath(attrEntity.getCatelogId()));

        return vo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateAttr(AttrVo attr) {
        this.baseMapper.updateById(attr);

        Integer count = this.attrAttrgroupRelationDao.selectCount(
                Wrappers.<AttrAttrgroupRelationEntity>lambdaUpdate()
                        .eq(AttrAttrgroupRelationEntity::getAttrId, attr.getAttrId())
        );

        AttrAttrgroupRelationEntity entity = new AttrAttrgroupRelationEntity();
        entity.setAttrGroupId(attr.getAttrGroupId());
        entity.setAttrName(attr.getAttrName());

        if (attr.getAttrType() == ProductConstant.AttrEnum.TYPE_ATTR_BASE.getCode()
                && Objects.nonNull(attr.getAttrGroupId())) {
            entity.setAttrId(attr.getAttrId());
            entity.setGroupName(this.attrGroupService.getById(attr.getAttrGroupId()).getAttrGroupName());
        }
        entity.setCatelogName(this.categoryService.getById(attr.getCatelogId()).getName());
        // 有值存在,直接更新
        if (count > 0) {
            this.attrAttrgroupRelationDao.update(
                    entity,
                    Wrappers.<AttrAttrgroupRelationEntity>lambdaUpdate()
                            .eq(AttrAttrgroupRelationEntity::getAttrId, attr.getAttrId())

            );
            return;
        }
        this.attrAttrgroupRelationDao.insert(entity);
    }

    @Override
    public List<AttrEntity> getRelationAttr(Long attrGroupId) {
        List<AttrAttrgroupRelationEntity> entities = this.attrAttrgroupRelationDao.selectList(
                Wrappers.<AttrAttrgroupRelationEntity>lambdaQuery()
                        .eq(AttrAttrgroupRelationEntity::getAttrGroupId, attrGroupId)
        );
        List<Long> collect = entities.stream().map(AttrAttrgroupRelationEntity::getAttrId).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(collect)) {
            return this.baseMapper.selectBatchIds(collect);
        }
        return Collections.emptyList();
    }

    @Override
    public void relationDelete(List<AttrGroupRelationVo> voList) {
        this.baseMapper.deleteBatch(voList);
    }

    @Override
    public PageUtils noAttrGroupRelation(Map<String, Object> params, Long attrGroupId) {

        String key = (String) params.get("key");

        AttrGroupEntity groupEntity = this.attrGroupService.getById(attrGroupId);
        Long catelogId = groupEntity.getCatelogId();

        BaseMapper<AttrGroupEntity> attrGroupBaseMapper = this.attrGroupService.getBaseMapper();
        List<AttrGroupEntity> groups = attrGroupBaseMapper
                .selectList(Wrappers.<AttrGroupEntity>lambdaQuery()
                        .eq(AttrGroupEntity::getCatelogId, catelogId)
                );

        List<Long> groupIds = groups.stream()
                .map(AttrGroupEntity::getAttrGroupId)
                .collect(Collectors.toList());

        List<AttrAttrgroupRelationEntity> entityList = this.attrAttrgroupRelationDao.selectList(
                Wrappers.<AttrAttrgroupRelationEntity>lambdaQuery()
                        .in(AttrAttrgroupRelationEntity::getAttrGroupId, groupIds)
        );

        List<Long> attrIds = entityList.stream()
                .map(AttrAttrgroupRelationEntity::getAttrId)
                .collect(Collectors.toList());

        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                Wrappers.<AttrEntity>lambdaQuery()
                        .eq(AttrEntity::getCatelogId, catelogId)
                        .eq(AttrEntity::getAttrType, ProductConstant.AttrEnum.TYPE_ATTR_BASE.getCode())
                        .notIn(CollectionUtils.isNotEmpty(attrIds), AttrEntity::getAttrId, attrIds)
                        .like(StringUtils.isNotBlank(key), AttrEntity::getAttrName, key)
        );
        return new PageUtils(page);
    }

    @Override
    public List<SpuBaseAttrVo> selectBatchByCatalogId(Long catalogId) {
        return this.baseMapper.selectBatchByCatalogId(catalogId);
    }
}